package arduino.comm.connection;

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.TooManyListenersException;

public class SerialProgram implements Runnable {

    private CommPortIdentifier _portId = null;
    private SerialPort _serialPort = null;
    private DataInputStream _is;
    private int _baudRate = 19200;

    private final Thread readThread;
    private boolean _isArduino;

    /************************
     * Constructor definition
     ***********************/
    public SerialProgram(CommPortIdentifier portId, int baudRate) {

	_portId = portId;
	_baudRate = baudRate;

	/**********************
	 * Open the serial port
	 *********************/
	try {
	    _serialPort = (SerialPort) portId.open("Artificial Horizont", 2000);
	} catch (PortInUseException ex) {
	    System.err.println("Port already in use!");
	}

	// Get input stream
	try {
	    _is = new DataInputStream(_serialPort.getInputStream());
	} catch (IOException e) {
	    System.err.println("Cannot open Input Stream " + e);
	    _is = null;
	}

	try {
	    _serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
	} catch (UnsupportedCommOperationException ex) {
	    System.err.println("Wrong settings for the serial port: " + ex.getMessage());
	}

	try {
	    _serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
	} catch (UnsupportedCommOperationException ex) {
	    System.err.println("Check the flow control setting: " + ex.getMessage());
	}

	// Add an event Listener
	try {
	    _serialPort.addEventListener(new SerialReader(_is));
	} catch (TooManyListenersException ev) {
	    System.err.println("Too many Listeners! " + ev);
	}

	// Advise if data available to be read on the port
	_serialPort.notifyOnDataAvailable(true);

	// Define a Thread for reading
	readThread = new Thread(this);
	readThread.start();
    }

    @Override
    public void run() {
	try {
	    // Thread.yield();
	    Thread.sleep(20000);
	} catch (InterruptedException e) {
	}
    }

    public boolean isArduino() {
	return _isArduino;
    }

}